package com.gj.sendall;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Pattern;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType.LaunchOptions;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Route;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrFormatter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author ShiQiang
 **/
@ServerEndpoint("/test")
@Component
@Slf4j
public class MyWebsocketServer {
    /**
     * 存放所有在线的客户端
     */
	private LinkedBlockingQueue<String> takeQueue = new LinkedBlockingQueue<>(10);
    private final Map<String, Session> conns = new ConcurrentHashMap<>();
    private final Map<String, Page> pages = new ConcurrentHashMap<>();
    public ExecutorService executor = Executors.newFixedThreadPool(1);
    private final Gson gson = new Gson();
    private boolean noStart = true;
    
    
    static BrowserContext browser;
    static {
    	Playwright playwright = Playwright.create();
    	ArrayList<String> arrayList = new ArrayList<>(); 
  	  	LaunchOptions options = new LaunchOptions().setArgs(arrayList).setHeadless(false);
       // arrayList.add("--no-sandbox");
        //arrayList.add("--disable-setuid-sandbox");
        Browser browsers = playwright.chromium().launch(options); 
        browser = browsers.newContext(); 
        
    }
    
    @OnOpen
    public void onOpen(Session session) {
    	Map<String, List<String>> parmas = session.getRequestParameterMap(); 
    	log.info("有新的客户端连接了: {}", parmas); 
    	String roomid = parmas.get("roomid").get(0);
    	if(StringUtils.isEmpty(roomid)){
    		try {
				session.close();
			} catch (IOException e) { 
				e.printStackTrace();
			}
    	}else{
    		//将新用户存入在线的组
    		try {
				Page page = pages.get(roomid);
				if(page != null){
					page.close();
				} 
				conns.put(parmas.get("roomid").get(0), session);
		        startRoomPage(browser.newPage(),session,roomid);
		        startSendMsg();
			} catch (Exception e) { 
				e.printStackTrace();
			} 
    	} 
    }

    /**
     * 客户端关闭
     * @param session session
     */
    @OnClose
    public void onClose(Session session) { 
    	Map<String, List<String>> parmas = session.getRequestParameterMap(); 
        log.info("有用户断开了, id为:{}", session.getId());
        //将掉线的用户移除在线的组里
        conns.remove(parmas.get("roomid").get(0));
    }

    /**
     * 发生错误
     * @param throwable e
     */
    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }


    /**
     * 收到客户端发来消息
     * @param message  消息对象
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("服务端收到客户端发来的消息: {}", message);
       // this.sendAll(message);
    }


    /**
     * 群发消息
     * @param message 消息内容
     */
    private void sendAll(String message) {
        for (Map.Entry<String, Session> sessionEntry : conns.entrySet()) {
            sessionEntry.getValue().getAsyncRemote().sendText(message);
        }
    }
    
    
    
    public void startRoomPage(Page page,Session RoomConn,String RoomId) throws Exception{
    	page.setDefaultNavigationTimeout(0);  
    	page.navigate(StrFormatter.format("https://live.douyin.com/{}", RoomId));
    	//page.setRequestInterception(true);
    	//page.setCacheEnabled(false);   
    	 
    	
    	Path imageFile = Paths.get("E:\\code\\git_work\\springboot-websocket-master\\src\\main\\resources\\douyin\\dd.js"); 
    	page.route(Pattern.compile("common-utils-message*"), route -> {  
         	 
         	Map<String,String> headers = Maps.newHashMap();
         	headers.put("Access-Control-Allow-Origin",  "*"); 
         	route.fulfill(new Route.FulfillOptions().setBodyBytes(FileUtil.readBytes(imageFile.toFile()))); 
         	
         	/*route.fulfill(new Route.FulfillOptions()
         		    .setStatus(200)
         		    .setHeaders(headers)
         		    .setContentType("application/javascript")
         		    .setBody(FileUtil.readString(imageFile.toString(), "utf-8")));*/
         	System.out.println("已替换:"+ route.request().url());
	          
        });
    	page.exposeFunction("sendRoomMesssage", args -> {
    		//takeQueue.offer(String.valueOf(args[0]));
    		System.out.println(String.valueOf(args[0]));
    		
    		/*page.onWebSocket(ws ->{
    			ws.se
    		});*/
    		
    		return null;
      	 }); 
        page.reload();
    } 
    
    public synchronized void startSendMsg(){
    	if(noStart){ 
    		SendMsgRun msgRun = new SendMsgRun(takeQueue,conns);
    		executor.execute(msgRun); 
    		noStart = false;
    	}
    } 
}
